const Visitor = require("../models/Visitor");
const TokenTransaction = require("../models/TokenTransaction");
const UserBenefit = require("../models/UserBenefit");
const { sequelize } = require("../config/database");
const { v4: uuidv4 } = require("uuid");
const { Op } = require("sequelize");

// ========== 代币来源管理辅助函数 ==========

/**
 * 按比例扣除代币 - 用户无感知，后台精确统计
 * 保持各类代币的相对比例，确保统计的准确性
 */
const deductTokensProportionally = async (visitor, amount, transaction) => {
  // 确保数值类型（DECIMAL字段返回字符串）
  const totalBalance = parseFloat(visitor.tokens_balance);
  
  if (totalBalance < amount) {
    throw new Error("Insufficient tokens");
  }

  // 如果总余额为0，直接返回
  if (totalBalance === 0) {
    throw new Error("No tokens available");
  }

  // 计算各类代币的比例（确保数值类型）
  const purchasedRatio = parseFloat(visitor.tokens_purchased) / totalBalance;
  const promotionalRatio = parseFloat(visitor.tokens_promotional) / totalBalance;
  const compensatedRatio = parseFloat(visitor.tokens_compensated) / totalBalance;

  // 对于小数代币，使用精确计算而不是向下取整
  let deductions = {
    purchased: amount * purchasedRatio,
    promotional: amount * promotionalRatio,
    compensated: amount * compensatedRatio
  };

  // 处理浮点数精度问题，确保扣除总量正确
  const totalDeducted = deductions.purchased + deductions.promotional + deductions.compensated;
  const difference = Math.abs(amount - totalDeducted);
  
  // 如果有微小的浮点数误差（< 0.001），进行调整
  if (difference > 0.001) {
    // 将差值按最大余额优先原则分配
    if (visitor.tokens_purchased >= visitor.tokens_promotional && 
        visitor.tokens_purchased >= visitor.tokens_compensated) {
      deductions.purchased += (amount - totalDeducted);
    } else if (visitor.tokens_promotional >= visitor.tokens_compensated) {
      deductions.promotional += (amount - totalDeducted);
    } else {
      deductions.compensated += (amount - totalDeducted);
    }
  }

  // 验证扣除量不超过各类余额（考虑小数精度）
  if (deductions.purchased > parseFloat(visitor.tokens_purchased) + 0.001 ||
      deductions.promotional > parseFloat(visitor.tokens_promotional) + 0.001 ||
      deductions.compensated > parseFloat(visitor.tokens_compensated) + 0.001) {
    throw new Error("Calculation error in token deduction");
  }

  // 更新各类代币余额（保留小数精度）
  const newBalances = {
    tokens_purchased: Math.round((parseFloat(visitor.tokens_purchased) - deductions.purchased) * 1000) / 1000,
    tokens_promotional: Math.round((parseFloat(visitor.tokens_promotional) - deductions.promotional) * 1000) / 1000,
    tokens_compensated: Math.round((parseFloat(visitor.tokens_compensated) - deductions.compensated) * 1000) / 1000,
    tokens_balance: Math.round((parseFloat(visitor.tokens_balance) - amount) * 1000) / 1000
  };

  await visitor.update(newBalances, { transaction });

  return { deductions, newBalances };
};

/**
 * 增加特定来源的代币
 */
const addTokensBySource = async (visitor, amount, source, transaction) => {
  const updates = {
    tokens_balance: Math.round((parseFloat(visitor.tokens_balance) + amount) * 1000) / 1000
  };

  switch (source) {
    case 'purchased':
      updates.tokens_purchased = Math.round((parseFloat(visitor.tokens_purchased) + amount) * 1000) / 1000;
      break;
    case 'promotional':
      updates.tokens_promotional = Math.round((parseFloat(visitor.tokens_promotional) + amount) * 1000) / 1000;
      break;
    case 'compensated':
      updates.tokens_compensated = Math.round((parseFloat(visitor.tokens_compensated) + amount) * 1000) / 1000;
      break;
    default:
      throw new Error("Invalid token source");
  }

  await visitor.update(updates, { transaction });
  return updates;
};

/**
 * 退还代币（按原来扣除的比例退还）
 */
const refundTokensProportionally = async (visitor, totalAmount, deductionRecord, transaction) => {
  // 如果没有扣除记录，默认退还到补偿代币
  if (!deductionRecord) {
    return await addTokensBySource(visitor, totalAmount, 'compensated', transaction);
  }

  const updates = {
    tokens_balance: Math.round((parseFloat(visitor.tokens_balance) + totalAmount) * 1000) / 1000,
    tokens_purchased: Math.round((parseFloat(visitor.tokens_purchased) + (deductionRecord.purchased || 0)) * 1000) / 1000,
    tokens_promotional: Math.round((parseFloat(visitor.tokens_promotional) + (deductionRecord.promotional || 0)) * 1000) / 1000,
    tokens_compensated: Math.round((parseFloat(visitor.tokens_compensated) + (deductionRecord.compensated || 0)) * 1000) / 1000
  };

  await visitor.update(updates, { transaction });
  return updates;
};

// ========== 原有的代币操作函数（更新后） ==========

// 使用代币 - 传统直接扣除方式（保留兼容性）
exports.consumeTokens = async (req, res) => {
  const { user_uuid, amount, description = "使用代币", request_id } = req.body;

  if (!user_uuid || !amount || amount <= 0) {
    return res.status(400).json({ error: "Invalid parameters" });
  }

  // 幂等性检查
  if (request_id) {
    const existingTransaction = await TokenTransaction.findOne({
      where: { request_id, type: 'consumption' }
    });
    
    if (existingTransaction) {
      return res.json({
        success: true,
        consumed: Math.abs(existingTransaction.amount),
        balance_after: existingTransaction.balance_after,
        message: "代币已消费（重复请求）",
        transaction_id: existingTransaction.id
      });
    }
  }

  const transaction = await sequelize.transaction();

  try {
    // 行级锁，防止并发修改
    const visitor = await Visitor.findOne({
      where: { uuid: user_uuid },
      transaction,
      lock: transaction.LOCK.UPDATE,
    });

    if (!visitor) {
      await transaction.rollback();
      return res.status(404).json({ error: "User not found" });
    }

    if (parseFloat(visitor.tokens_balance) < amount) {
      await transaction.rollback();
      return res.status(400).json({
        error: "Insufficient tokens",
        current_balance: parseFloat(visitor.tokens_balance),
        required: amount,
      });
    }

    const newBalance = parseFloat(visitor.tokens_balance) - amount;

    // 更新用户余额
    await visitor.update(
      {
        tokens_balance: newBalance,
      },
      { transaction }
    );

    // 记录消费
    const tokenTransaction = await TokenTransaction.create(
      {
        user_uuid,
        type: "consumption",
        amount: -amount,
        balance_after: newBalance,
        description,
        request_id,
        status: 'confirmed'
      },
      { transaction }
    );

    // 更新用户权益统计
    const userBenefit = await UserBenefit.findOne({
      where: { user_uuid },
      transaction,
    });

    if (userBenefit) {
      await userBenefit.update(
        {
          total_tokens_used: userBenefit.total_tokens_used + amount,
        },
        { transaction }
      );
    }

    await transaction.commit();

    res.json({
      success: true,
      consumed: amount,
      balance_after: newBalance,
      message: "代币消费成功",
      transaction_id: tokenTransaction.id
    });
  } catch (err) {
    await transaction.rollback();
    console.error("代币消费失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 预扣代币 - 高并发安全的两阶段扣除
exports.reserveTokens = async (req, res) => {
  const { 
    user_uuid, 
    service_type, // 服务类型 (text, img, voice, video) - 必需参数
    related_service,
    expires_in_minutes = 30, // 默认30分钟过期
    request_id
  } = req.body;

  // 检查必需参数
  if (!user_uuid || !service_type) {
    return res.status(400).json({ error: "user_uuid and service_type are required" });
  }

  // 导入服务代币消费配置
  const { ServiceTokenCost } = require('../config/pricing');

  const transaction = await sequelize.transaction();
  
  try {
    // 先获取用户信息，检查会员状态
    const visitor = await Visitor.findOne({
      where: { uuid: user_uuid },
      transaction,
      lock: transaction.LOCK.UPDATE,
    });

    if (!visitor) {
      await transaction.rollback();
      return res.status(404).json({ error: "User not found" });
    }

    // 检查用户是否是会员
    const now = new Date();
    const isMember = visitor.membership_expires_at && visitor.membership_expires_at > now;

    // 根据服务类型和会员状态确定预扣金额
    let reserveAmount;
    if (isMember) {
      // 会员价格
      const memberPricing = {
        'text': 0, // 文本生成免费
        'img':8,  // 图片生成6token
        'voice': 4, // 声音生成4token
        'video': 20 // 视频生成20token
      };
      reserveAmount = memberPricing[service_type];
    } else {
      // 非会员使用原价
      reserveAmount = ServiceTokenCost[service_type];
    }

    if (reserveAmount === undefined) {
      await transaction.rollback();
    return res.status(400).json({ 
      error: "Invalid service type",
      supported_types: Object.keys(ServiceTokenCost)
    });
  }

  // 准备预扣交易的通用数据
  const reserve_id = uuidv4();
  const expires_at = new Date(Date.now() + expires_in_minutes * 60 * 1000);

  // 根据服务类型生成描述
  const generateDescription = (serviceType, amount) => {
    const serviceMap = {
      'text': '文本生成',
      'img': '图片生成', 
      'voice': '声音生成',
      'video': '视频生成'
    };
    
    const serviceName = serviceMap[serviceType] || '服务';
    return `${serviceName}_预扣除${amount}代币`;
  };

  const description = generateDescription(service_type, reserveAmount);

  // 幂等性检查
  if (request_id) {
    const existingTransaction = await TokenTransaction.findOne({
      where: { request_id, type: 'reserve' }
    });
    
    if (existingTransaction) {
      await transaction.rollback();
      return res.json({
        success: true,
        reserved: Math.abs(existingTransaction.amount),
        reserve_id: existingTransaction.reserve_id,
        expires_at: existingTransaction.expires_at,
        message: "代币已预扣（重复请求）"
      });
    }
  }
  
  // 如果金额为0（会员的文本生成），创建预扣交易记录但不实际扣费
  if (reserveAmount === 0) {
    // 记录预扣交易
    await TokenTransaction.create({
      user_uuid,
      type: "reserve",
      amount: 0,  // 金额为0
      balance_after: parseFloat(visitor.tokens_balance),
      description: description,
      reserve_id,
      status: 'pending',
      expires_at,
      related_service,
      request_id,
      server_type: service_type, // 保存服务类型
      metadata: JSON.stringify({purchased: 0, promotional: 0, compensated: 0})
    }, { transaction });

    await transaction.commit();

    return res.json({
      success: true,
      reserved: 0,
      reserve_id,
      expires_at,
      balance_after: parseFloat(visitor.tokens_balance),
      message: "会员文本生成服务，代币预扣成功（金额为0）"
    });
  }

    if (parseFloat(visitor.tokens_balance) < reserveAmount) {
      await transaction.rollback();
      return res.status(400).json({
        error: "Insufficient tokens",
        current_balance: parseFloat(visitor.tokens_balance),
        required: reserveAmount,
      });
    }

    // 智能扣除代币（按优先级）
    const { deductions, newBalances } = await deductTokensProportionally(visitor, reserveAmount, transaction);

    // 记录预扣交易
    await TokenTransaction.create({
      user_uuid,
      type: "reserve",
      amount: -reserveAmount,
      balance_after: newBalances.tokens_balance,
      description: description,
      reserve_id,
      status: 'pending',
      expires_at,
      related_service,
      request_id,
      server_type: service_type, // 保存服务类型
      metadata: JSON.stringify(deductions)
    }, { transaction });

    await transaction.commit();

    res.json({
      success: true,
      reserved: reserveAmount,
      reserve_id,
      expires_at,
      balance_after: newBalances.tokens_balance,
      message: "代币预扣成功"
    });

  } catch (err) {
    await transaction.rollback();
    console.error("代币预扣失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 确认预扣代币 - 正式扣除
exports.confirmReservedTokens = async (req, res) => {
  const { reserve_id, service_type } = req.body;

  // 根据服务类型生成确认描述
  const generateConfirmDescription = (serviceType, amount) => {
    const serviceMap = {
      'text': '文本生成',
      'img': '图片生成', 
      'voice': '声音生成',
      'video': '视频生成'
    };
    
    const serviceName = serviceMap[serviceType] || '服务';
    return `${serviceName}_确认扣除${amount}代币`;
  };

  if (!reserve_id) {
    return res.status(400).json({ error: "Reserve ID is required" });
  }

  const transaction = await sequelize.transaction();

  try {
    // 查找预扣记录
    const reserveTransaction = await TokenTransaction.findOne({
      where: { 
        reserve_id, 
        type: 'reserve',
        status: 'pending'
      },
      transaction,
      lock: transaction.LOCK.UPDATE
    });

    if (!reserveTransaction) {
      await transaction.rollback();
      return res.status(404).json({ 
        error: "Reserve transaction not found or already processed" 
      });
    }

    // 检查是否过期
    if (reserveTransaction.expires_at && new Date() > reserveTransaction.expires_at) {
      await transaction.rollback();
      return res.status(400).json({ 
        error: "Reserve transaction has expired" 
      });
    }

    const user_uuid = reserveTransaction.user_uuid;
    const amount = Math.abs(reserveTransaction.amount);

    // 生成确认描述
    const description = service_type ? 
      generateConfirmDescription(service_type, amount) : 
      `确认扣除${amount}代币`;

    // 直接更新原有预扣记录的状态和描述
    await reserveTransaction.update({
      status: 'confirmed',
      description: description
    }, { transaction });

    // 更新用户权益统计 (即使amount为0也记录，保持完整的统计记录)
    const userBenefit = await UserBenefit.findOne({
      where: { user_uuid },
      transaction,
    });

    if (userBenefit) {
      await userBenefit.update({
        total_tokens_used: userBenefit.total_tokens_used + amount,
      }, { transaction });
    }

    await transaction.commit();

    res.json({
      success: true,
      confirmed: amount,
      reserve_id,
      balance_after: reserveTransaction.balance_after,
      message: "代币使用确认成功"
    });

  } catch (err) {
    await transaction.rollback();
    console.error("代币确认失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 取消预扣代币 - 退还代币
exports.cancelReservedTokens = async (req, res) => {
  const { reserve_id, service_type } = req.body;

  // 根据服务类型生成取消描述
  const generateCancelDescription = (serviceType, amount) => {
    const serviceMap = {
      'text': '文本生成',
      'img': '图片生成', 
      'voice': '声音生成',
      'video': '视频生成'
    };
    
    const serviceName = serviceMap[serviceType] || '服务';
    return `${serviceName}_取消扣除${amount}代币`;
  };

  if (!reserve_id) {
    return res.status(400).json({ error: "Reserve ID is required" });
  }

  const transaction = await sequelize.transaction();

  try {
    // 查找预扣记录
    const reserveTransaction = await TokenTransaction.findOne({
      where: { 
        reserve_id, 
        type: 'reserve',
        status: 'pending'
      },
      transaction,
      lock: transaction.LOCK.UPDATE
    });

    if (!reserveTransaction) {
      await transaction.rollback();
      return res.status(404).json({ 
        error: "Reserve transaction not found or already processed" 
      });
    }

    const user_uuid = reserveTransaction.user_uuid;
    const amount = Math.abs(reserveTransaction.amount);

    // 生成取消描述
    const description = service_type ? 
      generateCancelDescription(service_type, amount) : 
      `取消扣除${amount}代币`;

    // 行级锁获取用户信息
    const visitor = await Visitor.findOne({
      where: { uuid: user_uuid },
      transaction,
      lock: transaction.LOCK.UPDATE,
    });

    if (!visitor) {
      await transaction.rollback();
      return res.status(404).json({ error: "User not found" });
    }

    // 解析原始扣除详情
    let originalDeductions = null;
    try {
      originalDeductions = reserveTransaction.metadata ? JSON.parse(reserveTransaction.metadata) : null;
    } catch (e) {
      console.warn('无法解析预扣记录的metadata:', reserveTransaction.id);
    }

    // 按比例退还代币
    const newBalances = await refundTokensProportionally(visitor, amount, originalDeductions, transaction);

    // 直接更新原有预扣记录：状态、描述、金额（改为正数表示退还）、余额
    await reserveTransaction.update({
      status: 'canceled',
      description: description,
      amount: amount, // 改为正数表示退还
      balance_after: newBalances.tokens_balance
    }, { transaction });

    await transaction.commit();

    res.json({
      success: true,
      canceled: amount,
      refunded: amount,
      reserve_id,
      balance_after: newBalances.tokens_balance,
      message: "代币预扣已取消，代币已退还"
    });

  } catch (err) {
    await transaction.rollback();
    console.error("代币取消失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 获取用户代币信息
exports.getUserTokenInfo = async (req, res) => {
  const { user_uuid } = req.body;

  try {
    const visitor = await Visitor.findOne({
      where: { uuid: user_uuid },
    });

    if (!visitor) {
      return res.status(404).json({ error: "User not found" });
    }

    const now = new Date();
    const isMember =
      visitor.membership_expires_at && visitor.membership_expires_at > now;

    // 获取会员等级信息
    let membershipTier = null;
    if (isMember) {
      const userBenefit = await UserBenefit.findOne({
        where: { user_uuid }
      });
      membershipTier = userBenefit ? userBenefit.membership_tier : null;
    }

    res.json({
      user_uuid,
      tokens_balance: parseFloat(visitor.tokens_balance),
      is_member: isMember,
      membership_tier: membershipTier,
      membership_expires_at: visitor.membership_expires_at,
      membership_status: isMember ? "active" : "expired",
    });
  } catch (err) {
    console.error("获取用户代币信息失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 获取用户代币交易记录
exports.getTokenTransactions = async (req, res) => {
  const { user_uuid, page = 1, limit = 20, type, status } = req.query;
  try {
    const offset = (page - 1) * limit;
    
    const whereClause = { user_uuid };
    if (type) whereClause.type = type;
    if (status) whereClause.status = status;

    const { count, rows } = await TokenTransaction.findAndCountAll({
      where: whereClause,
      attributes: ['id', 'type', 'amount', 'balance_after', 'description', 'status', 'createdAt'],
      order: [["createdAt", "DESC"]],
      limit: parseInt(limit),
      offset: parseInt(offset),
    });

    // 简化交易记录，移除敏感信息
    const simplifiedTransactions = rows.map(tx => ({
      id: tx.id,
      type: tx.type,
      amount: tx.amount,
      balance_after: tx.balance_after,
      description: tx.description,
      status: tx.status,
      created_at: tx.createdAt
    }));

    res.json({
      transactions: simplifiedTransactions,
      pagination: {
        total: count,
        page: parseInt(page),
        limit: parseInt(limit),
        pages: Math.ceil(count / limit),
      },
    });
  } catch (err) {
    console.error("获取代币交易记录失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 获取预扣状态
exports.getReserveStatus = async (req, res) => {
  const { reserve_id } = req.params;

  if (!reserve_id) {
    return res.status(400).json({ error: "Reserve ID is required" });
  }

  try {
    const reserveTransaction = await TokenTransaction.findOne({
      where: { 
        reserve_id, 
        type: 'reserve'
      }
    });

    if (!reserveTransaction) {
      return res.status(404).json({ 
        error: "Reserve transaction not found" 
      });
    }

    const isExpired = reserveTransaction.expires_at && new Date() > reserveTransaction.expires_at;

    res.json({
      reserve_id,
      status: reserveTransaction.status,
      amount: Math.abs(reserveTransaction.amount),
      expires_at: reserveTransaction.expires_at,
      is_expired: isExpired,
      related_service: reserveTransaction.related_service,
      created_at: reserveTransaction.createdAt
    });

  } catch (err) {
    console.error("获取预扣状态失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 批量清理过期的预扣交易
exports.cleanupExpiredReservations = async (req, res) => {
  const transaction = await sequelize.transaction();

  try {
    const now = new Date();
    
    // 查找所有过期的预扣交易
    const expiredReservations = await TokenTransaction.findAll({
      where: {
        type: 'reserve',
        status: 'pending',
        expires_at: {
          [Op.lt]: now
        }
      },
      transaction,
      lock: transaction.LOCK.UPDATE
    });

    let cleanedCount = 0;
    let refundedTokens = 0;

    for (const reservation of expiredReservations) {
      const user_uuid = reservation.user_uuid;
      const amount = Math.abs(reservation.amount);

      // 获取用户信息并加锁
      const visitor = await Visitor.findOne({
        where: { uuid: user_uuid },
        transaction,
        lock: transaction.LOCK.UPDATE,
      });

      if (visitor) {
        // 解析原始扣除详情
        let originalDeductions = null;
        try {
          originalDeductions = reservation.metadata ? JSON.parse(reservation.metadata) : null;
        } catch (e) {
          console.warn('无法解析过期预扣记录的metadata:', reservation.id);
        }

        // 按比例退还代币
        const newBalances = await refundTokensProportionally(visitor, amount, originalDeductions, transaction);

        // 直接更新原有预扣记录：状态、描述、金额（改为正数表示退还）、余额
        await reservation.update({
          status: 'canceled',
          description: `系统自动清理过期预扣_退还${amount}代币`,
          amount: amount, // 改为正数表示退还
          balance_after: newBalances.tokens_balance
        }, { transaction });

        cleanedCount++;
        refundedTokens += amount;
      }
    }

    await transaction.commit();

    res.json({
      success: true,
      cleaned_count: cleanedCount,
      refunded_tokens: refundedTokens,
      message: `成功清理 ${cleanedCount} 个过期预扣，退还 ${refundedTokens} 个代币`
    });

  } catch (err) {
    await transaction.rollback();
    console.error("清理过期预扣失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 获取用户待处理的预扣列表
exports.getUserPendingReservations = async (req, res) => {
  const { user_uuid } = req.params;

  try {
    const pendingReservations = await TokenTransaction.findAll({
      where: {
        user_uuid,
        type: 'reserve',
        status: 'pending'
      },
      order: [['createdAt', 'DESC']]
    });

    const now = new Date();
    const formattedReservations = pendingReservations.map(reservation => {
      const isExpired = reservation.expires_at && now > reservation.expires_at;
      return {
        reserve_id: reservation.reserve_id,
        amount: Math.abs(reservation.amount),
        expires_at: reservation.expires_at,
        is_expired: isExpired,
        related_service: reservation.related_service,
        description: reservation.description,
        created_at: reservation.createdAt
      };
    });

    res.json({
      user_uuid,
      pending_reservations: formattedReservations,
      total_pending: formattedReservations.length
    });

  } catch (err) {
    console.error("获取用户待处理预扣失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// ========== 新增：代币来源管理接口 ==========

// 发放购买代币（Stripe支付成功后调用）
exports.grantPurchasedTokens = async (req, res) => {
  const { user_uuid, amount, payment_order_id, description = "Stripe购买代币" } = req.body;

  if (!user_uuid || !amount || amount <= 0) {
    return res.status(400).json({ error: "Invalid parameters" });
  }

  const transaction = await sequelize.transaction();

  try {
    const visitor = await Visitor.findOne({
      where: { uuid: user_uuid },
      transaction,
      lock: transaction.LOCK.UPDATE,
    });

    if (!visitor) {
      await transaction.rollback();
      return res.status(404).json({ error: "User not found" });
    }

    // 增加购买代币
    const newBalances = await addTokensBySource(visitor, amount, 'purchased', transaction);

    // 记录交易
    await TokenTransaction.create({
      user_uuid,
      type: "purchase",
      amount: amount,
      balance_after: newBalances.tokens_balance,
      description,
      payment_order_id,
      status: 'confirmed',
      token_source: 'purchased'
    }, { transaction });

    await transaction.commit();

    res.json({
      success: true,
      granted: amount,
      source: 'purchased',
      balance_after: newBalances.tokens_balance,
      balances_by_source: {
        purchased: newBalances.tokens_purchased,
        promotional: newBalances.tokens_promotional,
        compensated: newBalances.tokens_compensated
      },
      message: "购买代币发放成功"
    });

  } catch (err) {
    await transaction.rollback();
    console.error("发放购买代币失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 发放活动代币
exports.grantPromotionalTokens = async (req, res) => {
  const { user_uuid, amount, description = "活动赠送代币", campaign_id } = req.body;

  if (!user_uuid || !amount || amount <= 0) {
    return res.status(400).json({ error: "Invalid parameters" });
  }

  const transaction = await sequelize.transaction();

  try {
    const visitor = await Visitor.findOne({
      where: { uuid: user_uuid },
      transaction,
      lock: transaction.LOCK.UPDATE,
    });

    if (!visitor) {
      await transaction.rollback();
      return res.status(404).json({ error: "User not found" });
    }

    // 增加活动代币
    const newBalances = await addTokensBySource(visitor, amount, 'promotional', transaction);

    // 记录交易
    await TokenTransaction.create({
      user_uuid,
      type: "promotional_grant",
      amount: amount,
      balance_after: newBalances.tokens_balance,
      description,
      status: 'confirmed',
      token_source: 'promotional',
      metadata: campaign_id ? JSON.stringify({ campaign_id }) : null
    }, { transaction });

    await transaction.commit();

    res.json({
      success: true,
      granted: amount,
      source: 'promotional',
      balance_after: newBalances.tokens_balance,
      balances_by_source: {
        purchased: newBalances.tokens_purchased,
        promotional: newBalances.tokens_promotional,
        compensated: newBalances.tokens_compensated
      },
      message: "活动代币发放成功"
    });

  } catch (err) {
    await transaction.rollback();
    console.error("发放活动代币失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 发放补偿代币
exports.grantCompensationTokens = async (req, res) => {
  const { user_uuid, amount, description = "补偿代币", reason } = req.body;

  if (!user_uuid || !amount || amount <= 0) {
    return res.status(400).json({ error: "Invalid parameters" });
  }

  const transaction = await sequelize.transaction();

  try {
    const visitor = await Visitor.findOne({
      where: { uuid: user_uuid },
      transaction,
      lock: transaction.LOCK.UPDATE,
    });

    if (!visitor) {
      await transaction.rollback();
      return res.status(404).json({ error: "User not found" });
    }

    // 增加补偿代币
    const newBalances = await addTokensBySource(visitor, amount, 'compensated', transaction);

    // 记录交易
    await TokenTransaction.create({
      user_uuid,
      type: "compensation_grant",
      amount: amount,
      balance_after: newBalances.tokens_balance,
      description,
      status: 'confirmed',
      token_source: 'compensated',
      metadata: reason ? JSON.stringify({ reason }) : null
    }, { transaction });

    await transaction.commit();

    res.json({
      success: true,
      granted: amount,
      source: 'compensated',
      balance_after: newBalances.tokens_balance,
      balances_by_source: {
        purchased: newBalances.tokens_purchased,
        promotional: newBalances.tokens_promotional,
        compensated: newBalances.tokens_compensated
      },
      message: "补偿代币发放成功"
    });

  } catch (err) {
    await transaction.rollback();
    console.error("发放补偿代币失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// 获取用户详细代币信息（包含来源分类）
exports.getUserDetailedTokenInfo = async (req, res) => {
  const { user_uuid } = req.body;

  try {
    const visitor = await Visitor.findOne({
      where: { uuid: user_uuid },
    });

    if (!visitor) {
      return res.status(404).json({ error: "User not found" });
    }

    const now = new Date();
    const isMember = visitor.membership_expires_at && visitor.membership_expires_at > now;

    // 获取会员等级信息
    let membershipTier = null;
    let nextTierTokensNeeded = null;
    
    if (isMember) {
      const userBenefit = await UserBenefit.findOne({
        where: { user_uuid }
      });
      membershipTier = userBenefit ? userBenefit.membership_tier : null;
    }

    res.json({
      user_uuid,
      total_balance: parseFloat(visitor.tokens_balance),
      balances_by_source: {
        purchased: parseFloat(visitor.tokens_purchased),
        promotional: parseFloat(visitor.tokens_promotional),
        compensated: parseFloat(visitor.tokens_compensated)
      },
      is_member: isMember,
      membership_tier: membershipTier,
      membership_expires_at: visitor.membership_expires_at,
      membership_status: isMember ? "active" : "expired"
    });

  } catch (err) {
    console.error("获取用户详细代币信息失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};



// 获取用户账单记录
exports.getUserBillingRecords = async (req, res) => {
  try {
    // 从请求对象中获取用户UUID (由auth中间件设置)
    const user_uuid = req.visitor.uuid;
    
    if (!user_uuid) {
      return res.status(400).json({ error: "User UUID is required" });
    }

    // 分页参数
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 20;
    const offset = (page - 1) * limit;

    // 可选的过滤参数
    const filter = {};
    if (req.query.status) filter.status = req.query.status;
    if (req.query.server_type) filter.server_type = req.query.server_type;

    // 构建查询条件
    const whereClause = {
      user_uuid,
      ...filter
    };

    // 查询用户的交易记录（带分页）
    const { count, rows } = await TokenTransaction.findAndCountAll({
      where: whereClause,
      attributes: [
        'id',
        'amount', 
        'balance_after', 
        'description', 
        'reserve_id',
        'payment_order_id',
        'status', 
        'server_type',
        'updatedAt',
        'type',
        'createdAt'
      ],
      order: [['updatedAt', 'DESC']],
      limit,
      offset
    });

    // 处理DECIMAL字段，转换为数字
    const formattedTransactions = rows.map(tx => ({
      id: tx.id,
      amount: parseFloat(tx.amount),
      balance_after: parseFloat(tx.balance_after),
      description: tx.description,
      reserve_id: ['purchase', 'subscription_grant'].includes(tx.type) ? tx.payment_order_id : tx.reserve_id,
      payment_order_id: tx.payment_order_id,
      status: tx.status,
      server_type: tx.server_type,
      updated_at: tx.updatedAt,
      created_at: tx.createdAt,
      type: tx.type
    }));

    res.json({
      success: true,
      user_uuid,
      billing_records: formattedTransactions,
      pagination: {
        total: count,
        page,
        limit,
        pages: Math.ceil(count / limit)
      }
    });
  } catch (err) {
    console.error("获取用户账单记录失败:", err.message);
    res.status(500).json({ error: "Internal server error" });
  }
};

// ========== 导出内部工具函数供其他模块使用 ==========
exports.addTokensBySource = addTokensBySource;
exports.refundTokensProportionally = refundTokensProportionally;
